import requests, datetime
from bs4 import BeautifulSoup
from support.dbms.helper import DBMS

class ZHIHUHOT:
    TAG = "ZHIHUHOT"
    HEADERS = {
        "authority": "www.zhihu.com",
        "user-agent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Mobile Safari/537.36",
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
    }
    DATABASE_NAME = "zhihu"
    TABLE_NAME_DATE = "hot"
    TABLE_NAME_DATA = "hot_data"

    __instance__ = None
    def __new__(cls, *args, **kwargs):
        if(not cls.__instance__): cls.__instance__ = object.__new__(cls)
        return cls.__instance__

    def getInstance():
        return ZHIHUHOT.__instance__

    def getTables(self):
        return [{"name":ZHIHUHOT.TABLE_NAME_DATE, "keys":[{"label":"DATE", "type":"CHAR", "length":10}]},{"name":ZHIHUHOT.TABLE_NAME_DATA, "keys":[{"label":"TITLE", "type":"TEXT"}, {"label":"LINK", "type":"TINYTEXT"}, {"label":"HOT", "type":"INT"},{"label":"DESCRIPTION", "type":"LONGTEXT"},{"label":"DATEID", "type":"INT"}]}]

    def fetchByHtml(self):
        res = requests.get("https://www.zhihu.com/hot", verify=False, headers=ZHIHUHOT.HEADERS)
        if res.status_code != 200:
            raise Exception("Failed to fetch html.")
        html = res.text
        soup = BeautifulSoup(html, 'html.parser')
        main_tag = soup.findAll('main')[0]
        list_tag = None
        for child in main_tag.children:
            if child.name == 'div':
                list_tag = child
                break
        if list_tag is None:
            raise Exception("Failed to find list tag.")
        results = []
        for item in list_tag.children:
            result = {}
            try:
                if item.name != "a":
                    continue
                link = item.attrs['href']
                texts = []
                is_second_div = False
                for tag in item.children:
                    if tag.name == 'div':
                        if is_second_div:
                            for sub_tag in tag.children:
                                if sub_tag.name in ['div', 'h1']:
                                    texts.append(sub_tag.text)
                        else:
                            is_second_div = True
                result["LINK"] = link
                result["TITLE"] = texts[0]
                if len(texts) == 2:
                    result["DESCRIPTION"] = ""
                    result["HOT"] = texts[1]
                else:
                    result["DESCRIPTION"] = texts[1]
                    result["HOT"] = texts[2]
                result["HOT"] = result["HOT"].split()[0]
                results.append(result)
            except Exception as e:
                Log.e(str(e))
        return results

    def fetchByApi(self):
        res = requests.get("https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total", verify=False, headers=ZHIHUHOT.HEADERS)
        data = res.json()
        results = []
        for item in data['data']:
            result = {
                "link": f"https://www.zhihu.com/question/{item['target']['id']}",
                "title": item['target']['title'],
                "description": item['target']['excerpt'],
                "hot": item['detail_text'].split()[0]
            }
            results.append(result)
        return results

    def fetchHot(self, oper):
        try:
            requests.packages.urllib3.disable_warnings()
            data = self.fetchByHtml()
        except:
            data = self.fetchByApi()
        self.__save__(data, oper)
    
    def __save__(self, data, oper):
        dateid = None
        date = datetime.datetime.now().strftime('%Y-%m-%d')
        ret = DBMS.query(oper, ZHIHUHOT.TABLE_NAME_DATE, {"ID":None, "DATE":date})
        if(ret):dateid = ret[0]["ID"]
        if(not dateid):dateid = DBMS.insert(oper, ZHIHUHOT.TABLE_NAME_DATE, {"DATE":date})
        for news in data:
            ret = DBMS.query(oper, ZHIHUHOT.TABLE_NAME_DATA, {"ID":None, "HOT":None, "DATEID":dateid, "LINK":news["LINK"]})
            if(ret):
                for item in ret:
                    if(item["HOT"] != news["HOT"]):DBMS.update(oper, ZHIHUHOT.TABLE_NAME_DATA, {"HOT":news["HOT"]}, {"ID":item["ID"]})
            else:
                news["DATEID"] = dateid
                DBMS.insert(oper, ZHIHUHOT.TABLE_NAME_DATA, news)

    
    def getData(self, num, *, year, month, day):
        result = None
        dbms = DBMS.getInstance()
        oper = dbms.connect(database=ZHIHUHOT.DATABASE_NAME)
        date = "{}-{:02}-{:02}".format(year, month, day)
        ret = DBMS.query(oper, ZHIHUHOT.TABLE_NAME_DATE, {"ID":None, "DATE":date})
        if(ret):
            dateid = ret[0]["ID"]
            result = DBMS.query(oper, ZHIHUHOT.TABLE_NAME_DATA, {"TITLE":None, "LINK":None, "HOT":None, "DATEID":dateid}, order=["HOT", "DESC"], limit=num)
        return result
